﻿using System;
using System.Linq;
using System.Text.RegularExpressions;

namespace Avin.Infrastructure.Entity
{
    [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
    public class ValidateAttribute : Attribute
    {
        public ValidateAttribute() { }

        /// <summary>
        /// 类属性对应的列名
        /// </summary>
        /// <param name="columnName"></param>
        public ValidateAttribute(string columnName)
        {
            ColumnName = columnName;
        }

        /// <summary>
        /// 是否允许为Null
        /// </summary>
        public bool CanNull = false;

        /// <summary>
        /// 允许默认值
        /// </summary>
        public bool CanDefault = false;

        /// <summary>
        /// 使用了默认值
        /// </summary>
        public bool IsUseDefault = false;

        /// <summary>
        /// 显示的名称
        /// </summary>
        public string DisplayName { get; set; }

        /// <summary>
        /// 类属性对应的列名
        /// </summary>
        public string ColumnName { get; set; }

        /// <summary>
        /// 格式化字符串
        /// </summary>
        public string Format { get; set; }

        /// <summary>
        /// 验证错误信息
        /// </summary>
        public string Error { get; set; }

        /// <summary>
        /// 验证数据
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public virtual string Validate(ref object value)
        {
            return "";
        }
    }

    public class IntegerValidateAttribute : ValidateAttribute
    {
        public IntegerValidateAttribute(string columnName) : base(columnName)
        {
        }

        /// <summary>
        /// 默认值
        /// </summary>
        public int DefaultValue = 1;

        /// <summary>
        /// 最小值
        /// </summary>
        public int MinValue = int.MinValue;

        /// <summary>
        /// 最大值
        /// </summary>
        public int MaxValue = int.MinValue;

        /// <summary>
        /// 指定值
        /// </summary>
        public int[] NominatedValue { get; set; }

        public override string Validate(ref object value)
        {
            if (string.IsNullOrWhiteSpace(Error))
            {
                Error = "{DisplayName}有误";
                if (!CanNull) Error += "，不能为空";
                if (MinValue != int.MinValue) Error += "，不能小于{MinValue}";
                if (MaxValue != int.MinValue) Error += "，不能大于{MaxValue}";
                Error += ";";
            }
            var isOk = true;
            if (!CanNull && value == null)
            {
                isOk = false;
            }
            else if (value != null)
            {
                int iValue = (int)value;
                if (NominatedValue != null && NominatedValue.Length > 0)
                {
                    isOk = NominatedValue.Contains(iValue);
                }
                else
                {
                    if (MinValue != int.MinValue && iValue < MinValue)
                    {
                        isOk = false;
                    }
                    else if (MaxValue != int.MinValue && iValue > MaxValue)
                    {
                        isOk = false;
                    }
                }
            }
            if (isOk)
            {
                return string.Empty;
            }
            else
            {
                if (CanDefault)
                {
                    IsUseDefault = true;
                    value = DefaultValue;
                    return string.Empty;
                }
                else
                {
                    return Error.Replace("{DisplayName}", DisplayName).Replace("{MinValue}", (MinValue != int.MinValue ? MinValue.ToString() : "")).Replace("{MaxValue}", (MaxValue != int.MinValue ? MaxValue.ToString() : ""));
                }
            }
        }
    }

    public class DateTimeValidateAttribute : ValidateAttribute
    {
        public DateTimeValidateAttribute(string columnName) : base(columnName)
        {
        }

        /// <summary>
        /// 默认值
        /// </summary>
        public DateTime DefaultValue = DateTime.Parse("1990-12-11 00:00:00");

        /// <summary>
        /// 最小值
        /// </summary>
        public DateTime MinValue = DateTime.MinValue;

        /// <summary>
        /// 最大值
        /// </summary>
        public DateTime MaxValue = DateTime.MaxValue;

        public override string Validate(ref object value)
        {
            if (string.IsNullOrWhiteSpace(Error))
            {
                Error = "{DisplayName}有误";
                if (!CanNull) Error += "，不能为空";
                if (MinValue != DateTime.MinValue) Error += "，不能早于{MinValue}";
                if (MaxValue != DateTime.MaxValue) Error += "，不能晚于{MaxValue}";
                Error += ";";
            }
            var isOk = true;
            if (!CanNull && value == null)
            {
                isOk = false;
            }
            else if (value != null)
            {
                var dt = (DateTime)value;
                if (MinValue != DateTime.MinValue && dt < MinValue)
                {
                    isOk = false;
                }
                else if (MaxValue != DateTime.MaxValue && dt > MaxValue)
                {
                    isOk = false;
                }
            }
            if (isOk)
            {
                return string.Empty;
            }
            else
            {
                if (CanDefault)
                {
                    IsUseDefault = true;
                    value = DefaultValue;
                    return string.Empty;
                }
                else
                {
                    return Error.Replace("{DisplayName}", DisplayName).Replace("{MinValue}", MinValue.ToString("yyyy-MM-dd HH:mm:ss")).Replace("{MaxValue}", MaxValue.ToString("yyyy-MM-dd HH:mm:ss"));
                }
            }
        }
    }

    public class StringValidateAttribute : ValidateAttribute
    {
        public StringValidateAttribute(string columnName) : base(columnName)
        {
        }

        /// <summary>
        /// 默认值
        /// </summary>
        public string DefaultValue = string.Empty;

        /// <summary>
        /// 最小长度
        /// </summary>
        public int MinLength = -1;

        /// <summary>
        /// 最大长度
        /// </summary>
        public int MaxLength = -1;

        /// <summary>
        /// 正则表达式
        /// </summary>
        public string Regex { get; set; }

        /// <summary>
        /// 指定值
        /// </summary>
        public string[] NominatedValue { get; set; }

        /// <summary>
        /// 大小写转换
        /// </summary>
        public StringCase StringCase { get; set; } = StringCase.None;

        public override string Validate(ref object value)
        {
            if (string.IsNullOrWhiteSpace(Error))
            {
                Error = "{DisplayName}有误";
                if (!CanNull) Error += "，不能为空";
                if (MinLength > -1) Error += "，长度不能小于{MinValue}";
                if (MaxLength > -1) Error += "，长度不能大于{MaxValue}";
                if (!string.IsNullOrWhiteSpace(Regex)) Error += "，数据输入不准确";
                Error += ";";
            }
            var isOk = true;
            if (!CanNull && value == null)
            {
                isOk = false;
            }
            else if (value != null)
            {
                string strValue = value.ToString().Trim();
                if (StringCase == StringCase.ToUpper)
                    strValue = strValue.ToUpper();
                else if (StringCase == StringCase.ToLower)
                    strValue = strValue.ToLower();
                value = strValue;
                if (NominatedValue != null && NominatedValue.Length > 0)
                {
                    isOk = NominatedValue.Contains(strValue);
                }
                else
                {
                    var iLength = strValue.Length;
                    if (MinLength > -1 && iLength < MinLength)
                    {
                        isOk = false;
                    }
                    else if (MaxLength > -1 && iLength > MaxLength)
                    {
                        isOk = false;
                    }
                    else if (!string.IsNullOrWhiteSpace(Regex))
                    {
                        var pattern = new Regex(Regex);
                        if (!pattern.Match(strValue).Success)
                        {
                            isOk = false;
                        }
                    }
                }
            }
            if (isOk)
            {
                return string.Empty;
            }
            else
            {
                if (CanDefault)
                {
                    IsUseDefault = true;
                    value = DefaultValue;
                    return string.Empty;
                }
                else
                {
                    return Error.Replace("{DisplayName}", DisplayName).Replace("{MinValue}", (MinLength > -1 ? MinLength.ToString() : "")).Replace("{MaxValue}", (MaxLength > -1 ? MaxLength.ToString() : ""));
                }
            }
        }
    }

    public class DecimalValidateAttribute : ValidateAttribute
    {
        public DecimalValidateAttribute(string columnName) : base(columnName)
        {
        }

        /// <summary>
        /// 默认值
        /// </summary>
        public decimal DefaultValue = 1;

        /// <summary>
        /// 最小值
        /// </summary>
        public decimal MinValue = decimal.MinValue;

        /// <summary>
        /// 最大值
        /// </summary>
        public decimal MaxValue = decimal.MinValue;

        /// <summary>
        /// 指定值
        /// </summary>
        public decimal[] NominatedValue { get; set; }

        public override string Validate(ref object value)
        {
            if (string.IsNullOrWhiteSpace(Error))
            {
                Error = "{DisplayName}有误";
                if (!CanNull) Error += "，不能为空";
                if (MinValue != decimal.MinValue) Error += "，不能小于{MinValue}";
                if (MaxValue != decimal.MinValue) Error += "，不能大于{MaxValue}";
                Error += ";";
            }
            var isOk = true;
            if (!CanNull && value == null)
            {
                isOk = false;
            }
            else if (value != null)
            {
                decimal iValue = (decimal)value;
                if (NominatedValue != null && NominatedValue.Length > 0)
                {
                    isOk = NominatedValue.Contains(iValue);
                }
                else
                {
                    if (MinValue != decimal.MinValue && iValue < MinValue)
                    {
                        isOk = false;
                    }
                    else if (MaxValue != decimal.MinValue && iValue > MaxValue)
                    {
                        isOk = false;
                    }
                }
            }
            if (isOk)
            {
                return string.Empty;
            }
            else
            {
                if (CanDefault)
                {
                    IsUseDefault = true;
                    value = DefaultValue;
                    return string.Empty;
                }
                else
                {
                    return Error.Replace("{DisplayName}", DisplayName).Replace("{MinValue}", (MinValue != decimal.MinValue ? MinValue.ToString() : "")).Replace("{MaxValue}", (MaxValue != decimal.MinValue ? MaxValue.ToString() : ""));
                }
            }
        }
    }

    public enum StringCase
    {
        /// <summary>
        /// 不处理
        /// </summary>
        None,

        /// <summary>
        /// 转大写
        /// </summary>
        ToUpper,

        /// <summary>
        /// 转小写
        /// </summary>
        ToLower
    }
}
